package com.excilys.formation.projet.ebanking.dao.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.joda.time.DateTime;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.excilys.formation.projet.ebanking.dao.api.IOperationDao;
import com.excilys.formation.projet.ebanking.modele.Operation;

public class OperationDaoImpl extends HibernateDaoSupport implements IOperationDao {

	@SuppressWarnings("unchecked")
	@Override
	public List<Operation> getOperationsNonCarte(int idCompte, DateTime date) {
		Criteria critere = getSession().createCriteria(Operation.class);
		critere.addOrder(Order.desc("date"));
		critere.createAlias("operationType", "opType");
		critere.createAlias("compte", "compte");
		critere.add(Restrictions.eq("compte.id", idCompte));
		critere.add(Restrictions.eq("opType.isCarte", false));
		critere.add(Restrictions.between("date", date.dayOfMonth().withMinimumValue(), date.dayOfMonth().withMaximumValue()));
		return critere.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Operation> getOperationsCarte(int idCompte, DateTime date) {
		Criteria critere = getSession().createCriteria(Operation.class);
		critere.addOrder(Order.desc("date"));
		critere.createAlias("operationType", "opType");
		critere.createAlias("compte", "compte");
		critere.add(Restrictions.eq("compte.id", idCompte));
		critere.add(Restrictions.eq("opType.isCarte", true));
		critere.add(Restrictions.between("date", date.dayOfMonth().withMinimumValue(), date.dayOfMonth().withMaximumValue()));
		return critere.list();
	}

	@Override
	public double getSommeOperationsCarte(int idCompte, DateTime date) {
		Criteria critere = getSession().createCriteria(Operation.class);
		critere.createAlias("operationType", "opType");
		critere.createAlias("compte", "compte");
		critere.add(Restrictions.eq("compte.id", idCompte));
		critere.add(Restrictions.eq("opType.isCarte", true));
		critere.add(Restrictions.between("date", date.dayOfMonth().withMinimumValue(), date.dayOfMonth().withMaximumValue()));
		critere.setProjection(Projections.sum("montant"));
		Double resultat = (Double) critere.uniqueResult();
		if (resultat == null) {
			return 0;
		}
		else {
			return resultat;
		}
	}

	@Override
	public void save(Operation operation) {
		getHibernateTemplate().save(operation);
	}

}
